package com.gable.report.service.impl;

import com.gable.report.common.util.DateFormatUtils;
import com.gable.report.common.util.DateUtils;
import com.gable.report.common.util.HttpHelper;
import com.gable.report.dao.IChartsForHospitalOverviewDao;
import com.gable.report.model.*;
import com.gable.report.service.ChartsForHospitalOverviewService;
import com.gable.report.util.MessageUtil;
import com.gable.report.util.TimeUnitConvertUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import static com.gable.report.util.ChartsUtil.getOverviewParamMap;
import static com.gable.report.util.MessageUtil.cleanContent;

/**
 * @Author: 杨青桦
 * @Description:  医院报表 总览页面业务逻辑层
 * @Date: 2018/1/17 11:05
 */
@Service
public class ChartsForHospitalOverviewServiceImpl implements ChartsForHospitalOverviewService {

    private final Log logger = LogFactory.getLog(this.getClass());

    @Autowired
    IChartsForHospitalOverviewDao chartsForHospitalOverviewDao;

    @Value("${hospital_webSocket_url}")
    private String hospitalWebSocketUrl;

    @Override
    public Map<String, Object> queryHospitalRegion(Long hospitalId) {
        return chartsForHospitalOverviewDao.queryHospitalRegion(hospitalId);
    }

    @Override
    public Map<String, Object> queryAssetsBase(Long hospitalId, ChartsOverviewQuery chartsOverviewQuery) {
        Map<String,Object> map = new HashMap<>();
        Map<String,Object> paramMap = getOverviewParamMap(hospitalId,chartsOverviewQuery);
        map.put("base",chartsForHospitalOverviewDao.queryAssetsNumAndPrice(paramMap));
        return map;
    }

    @Override
    public Map<String, Object> queryKeyPointAssets(Long hospitalId, ChartsOverviewQuery chartsOverviewQuery) {
        Map<String,Object> map = new HashMap<>();
        Map<String,Object> paramMap = getOverviewParamMap(hospitalId,chartsOverviewQuery);
        map.put("keyPointAssets",chartsForHospitalOverviewDao.queryKeyPointAssets(paramMap));
        return map;
    }

    /**
     * 业务修改：绩效分类改为筛选显示
     */
    @Override
    public Map<String, Object> queryPerformance(Long hospitalId, ChartsOverviewQuery chartsOverviewQuery) {
        Map<String,Object> map = new HashMap<>();
        Map<String,Object> paramMap = getOverviewParamMap(hospitalId,chartsOverviewQuery);
        ChartsOverviewConditionsView all = chartsForHospitalOverviewDao.queryPerformance(paramMap);
        map.put("performance",all);
        List<ChartsOverviewConditionsView> list = chartsForHospitalOverviewDao.queryPerformanceListForFirstType(paramMap);

        //计算“其他”的收入支出
        Long curOtherIncome = all.getCurIncome();
        Long curOtherExpenditure = all.getCurExpenditure();
        Long lastOtherIncome = all.getLastIncome();
        Long lastOtherExpenditure = all.getLastExpenditure();
        for(ChartsOverviewConditionsView cocv : list){
            curOtherIncome -= cocv.getCurIncome();
            curOtherExpenditure -= cocv.getCurExpenditure();
            lastOtherIncome -= cocv.getLastIncome();
            lastOtherExpenditure -= cocv.getLastExpenditure();
        }
        ChartsOverviewConditionsView other = new ChartsOverviewConditionsView();
        if(lastOtherIncome == 0L){
            other.setIncomeYoy(100.0);
        }else{
            other.setIncomeYoy((curOtherIncome-lastOtherIncome)*100.0/lastOtherIncome);
        }
        if(lastOtherExpenditure == 0L){
            other.setExpenditureYoy(100.0);
        }else{
            other.setExpenditureYoy((curOtherExpenditure-lastOtherExpenditure)*100.0/lastOtherExpenditure);
        }
        other.setId("-100");
        other.setName("其他");
        other.setCurIncome(curOtherIncome);
        other.setCurExpenditure(curOtherExpenditure);
        other.setLastIncome(lastOtherIncome);
        other.setLastExpenditure(lastOtherExpenditure);
        list.add(other);
        map.put("list",list);
        return map;
    }

    @Override
    public Map<String, Object> queryPerformanceForAll(Long hospitalId, ChartsOverviewQuery chartsOverviewQuery) {
        Map<String,Object> map = new HashMap<>();
        Map<String,Object> paramMap = getOverviewParamMap(hospitalId,chartsOverviewQuery);
        ChartsOverviewConditionsView all = chartsForHospitalOverviewDao.queryPerformance(paramMap);
        map.put("performance",all);
        return map;
    }

    @Override
    public Map<String, Object> queryAvgFaultRate(Long hospitalId) {
        Map<String,Object> map = new HashMap<>();
        Map<String,Object> paramMap = getOverviewParamMap(hospitalId,null);
        ChartsOverviewConditionsView all = chartsForHospitalOverviewDao.queryAvgFaultRate(paramMap);
        map.put("all",all);
        map.put("maintainSize",chartsForHospitalOverviewDao.queryMaintainSize(paramMap));
        List<ChartsOverviewConditionsView> list = chartsForHospitalOverviewDao.queryAvgFaultRateForFirstType(paramMap);

        //计算“其他”的故障次数和设备数量
        Long curOtherDeviceCounts = all.getCurDeviceCounts();
        Long curOtherToRepairCounts = all.getCurToRepairCounts();
        Long lastOtherDeviceCounts = all.getLastDeviceCounts();
        Long lastOtherToRepairCounts = all.getLastToRepairCounts();
        for(ChartsOverviewConditionsView cocv : list){
            curOtherDeviceCounts -= cocv.getCurDeviceCounts();
            curOtherToRepairCounts -= cocv.getCurToRepairCounts();
            lastOtherDeviceCounts -= cocv.getLastDeviceCounts();
            lastOtherToRepairCounts -= cocv.getLastToRepairCounts();
        }
        ChartsOverviewConditionsView other = new ChartsOverviewConditionsView();
        if(curOtherDeviceCounts == 0L){
            other.setCurAvgFaultRate(100.0);
        }else{
            other.setCurAvgFaultRate(curOtherToRepairCounts*100.0/curOtherDeviceCounts);
        }
        if(lastOtherDeviceCounts == 0L){
            other.setLastAvgFaultRate(100.0);
        }else{
            other.setLastAvgFaultRate(lastOtherToRepairCounts*100.0/lastOtherDeviceCounts);
        }

        if(other.getLastAvgFaultRate() == 0.0){
            other.setAvgFaultRateYoy(100.0);
        }else{
            other.setAvgFaultRateYoy((other.getCurAvgFaultRate() - other.getLastAvgFaultRate())*100.0/other.getLastAvgFaultRate());
        }
        other.setId("-100");
        other.setName("其他");
        other.setCurDeviceCounts(curOtherDeviceCounts);
        other.setCurToRepairCounts(curOtherToRepairCounts);
        other.setLastDeviceCounts(lastOtherDeviceCounts);
        other.setLastToRepairCounts(lastOtherToRepairCounts);
        list.add(other);
        map.put("list",list);
        return map;
    }

    @Override
    public Map<String, Object> queryMaintenanceConditionsByYear(Long hospitalId, ChartsOverviewQuery chartsOverviewQuery) {
        Map<String,Object> paramMap = getOverviewParamMap(hospitalId,chartsOverviewQuery);
        return chartsForHospitalOverviewDao.queryMaintenanceConditionsByYear(paramMap);
    }

    @Override
    public Map<String, Object> queryMaintenanceConditionsByMonth(Long hospitalId, ChartsOverviewQuery chartsOverviewQuery) {
        Map<String,Object> paramMap = getOverviewParamMap(hospitalId,chartsOverviewQuery);
        return chartsForHospitalOverviewDao.queryMaintenanceConditionsByMonth(paramMap);
    }

    @Override
    public Map<String, Object> queryWarningItems(Long hospitalId) {
        Map<String,Object> paramMap = getOverviewParamMap(hospitalId,null);
        return chartsForHospitalOverviewDao.queryWarningItems(paramMap);
    }

    @Override
    public Map<String, Object> queryWarningList(Long hospitalId, Integer tag) {
        Map<String,Object> paramMap = getOverviewParamMap(hospitalId,null);
        List<ChartsOverviewWarningView> list;
        switch (tag){
            case 1:
                list =  chartsForHospitalOverviewDao.queryExigencyRepairList(paramMap);
                break;
            case 2:
                list =  chartsForHospitalOverviewDao.queryHighRiskRepairList(paramMap);
                break;
            case 3:
                list =  chartsForHospitalOverviewDao.queryPlanCompulsoryList(paramMap);
                break;
            case 5:
                list =  chartsForHospitalOverviewDao.queryParameterEventList(paramMap);
                break;
            case 6:
                list =  chartsForHospitalOverviewDao.queryPlanUpkeepList(paramMap);
                break;
            case 7:
                list = chartsForHospitalOverviewDao.queryToDoList(paramMap);
                break;
            default:
                list = chartsForHospitalOverviewDao.queryExigencyRepairList(paramMap);
        }
        setContent(list,tag);
        Map<String,Object> returnMap = new HashMap<>();
        returnMap.put("list",list);
        return returnMap;
    }

    @Override
    public Map<String, Object> queryStatistics(Long hospitalId, ChartsOverviewQuery chartsOverviewQuery) {
        Map<String,Object> paramMap = getOverviewParamMap(hospitalId,chartsOverviewQuery);
        Map<String,Object> returnMap = new HashMap<>();
        List<ChartsOverviewStatisticsView> resultList = null;
        if(chartsOverviewQuery.getStatisticsType() == 0){
            resultList = chartsForHospitalOverviewDao.queryInspectionStatistics(paramMap);
        }else if(chartsOverviewQuery.getStatisticsType() == 1){
            resultList = chartsForHospitalOverviewDao.queryCompulsoryStatistics(paramMap);
        }else if(chartsOverviewQuery.getStatisticsType() == 2){
            resultList = chartsForHospitalOverviewDao.queryUpkeepStatistics(paramMap);
        }else{
            resultList = chartsForHospitalOverviewDao.queryRepairStatistics(paramMap);
        }
        returnMap.put("list",resultList);
        return returnMap;
    }

    @Override
    public Map<String, Object> queryUsageRateForFirstType(Long hospitalId, ChartsOverviewQuery chartsOverviewQuery) {
        Map<String,Object> paramMap = getOverviewParamMap(hospitalId,chartsOverviewQuery);
        List<Map<String,Object>> list = chartsForHospitalOverviewDao.queryUsageRateForFirstType(paramMap);
        Double[] usageRate = new Double[]{75.32,63.56,90.27,55.83,86.25,78.26};
        //使用率及标准次数使用假数据
        for(int i=0;i<list.size();i++){
            list.get(i).put("usageRate",usageRate[i]);
            list.get(i).put("standardCounts",(Integer)(list.get(i).get("usedCounts"))*100/usageRate[i]);
        }
        Iterator<Map<String,Object>> it = list.iterator();
        int totalUsedTimes = 0; //使用人次
        while(it.hasNext()) {
            Map<String,Object> obj = it.next();
            if((Integer)obj.get("usedCounts") == 0){
                obj.put("usageRate",0);
            }
            totalUsedTimes += (Integer)obj.get("usedCounts");
        }
        Map obj = new HashMap();
        Map<String,Object> totalMap = chartsForHospitalOverviewDao.queryUsedCounts(paramMap);
        /*obj.put("id",-100);
        obj.put("name","其他");
        obj.put("standardCounts",80000);
        obj.put("usedCounts",(Integer)totalMap.get("usedCounts")-totalUsedTimes);
        obj.put("usageRate",((Integer)totalMap.get("usedCounts")-totalUsedTimes)*100.0/80000);
        list.add(obj);*/
        Map<String,Object> returnMap = new HashMap<>();
        Map total = new HashMap();
        total.put("total",totalMap.get("usedCounts"));
        total.put("today",6438);
        total.put("usedTimeYoy",totalMap.get("usedCountsYoy"));
        returnMap.put("all",total);
        returnMap.put("list",list);
        return returnMap;
    }

    @Override
    public Map<String, Object> queryRepairRecords(Long hospitalId, ChartsOverviewQuery chartsOverviewQuery) {
        Map<String,Object> paramMap = getOverviewParamMap(hospitalId,chartsOverviewQuery);
        Map<String,Object> returnMap = new HashMap<>();
        List<Map<String,Object>> list = chartsForHospitalOverviewDao.queryRepairRecords(paramMap);
        if(!CollectionUtils.isEmpty(list)){
            returnMap.put("size",list.size());
        }
        returnMap.put("list",list);
        return returnMap;
    }

    /**
     *  业务修改：聊天只取当天的最后一条有用信息显示，内容为图片或者一句话 修改时间：2018-4-3 修改人：杨青桦
     * @return
     */
    @Override
    public Map<String, Object> queryRepairChatGroups(Long hospitalId, ChartsOverviewQuery chartsOverviewQuery) {
        Map<String,Object> paramMap = getOverviewParamMap(hospitalId,chartsOverviewQuery);
        Map<String,Object> returnMap = new HashMap<>();
        LocalDate today = LocalDate.now();
        System.out.println(today);
        int pageSize = 20; //聊天记录分页数量
        List<ChatGroup> list = chartsForHospitalOverviewDao.queryRepairChatGroups(paramMap);
        if(!CollectionUtils.isEmpty(list)){
            for(ChatGroup cg : list){
                StringBuffer sb = new StringBuffer();
                //查询最后一条有用信息聊天记录
                if(!CollectionUtils.isEmpty(cg.getList())){
                    for(int i=cg.getList().size()-1;i>=0;i--){
                        ChatGroupRecord cgr = cg.getList().get(i);
                        if(cgr.getRecordType() == 1){ //类型为聊天内容
                            sb.append(cgr.getCreateTime()).append(" ").append(cgr.getName());
                            String str = MessageUtil.splitNotNumber(cleanContent(cgr.getContentHtml()));
                            //消息处理有一个空格
                            if(" [图片]".equals(str)){
                                sb.append("发了一张图片");
                            }else{
                                sb.append("发了一句话");
                            }
                            //最后一次聊天记录时间判断
                            if(DateUtils.compare(cgr.getCreateTime(),today.toString() + " 00:00", DateFormatUtils.DATE_FORMAT2) == 1){
                                cg.setDisplay(1);
                            }else{
                                cg.setDisplay(0);
                            }
                            break;
                        }
                    }
                    cg.setTotalSize(cg.getList().size());   //总条数
                    cg.setTotalPage((int)Math.ceil(cg.getList().size()*1.0/pageSize)); //总页数
                    cg.setContent(sb.toString());
                    cg.setList(null); //清空list
                }
            }
        }
        returnMap.put("list",list);
        return returnMap;
    }

    @Override
    public void addMemberForGroup(Long hospitalId, Long userId) {
        List<Long> list = chartsForHospitalOverviewDao.queryRepairChatGroupIds(hospitalId);
        if(!CollectionUtils.isEmpty(list)){
            for(Long groupId : list){
                //检查群组中是否有成员
                int i = chartsForHospitalOverviewDao.checkChatMember(groupId,userId);
                if(i == 0){
                    Map<String,String> paramMap = new HashMap();
                    paramMap.put("id",String.valueOf(groupId));
                    paramMap.put("members",  String.valueOf(userId));
                    System.out.println("[\"" + userId + "\"]");
                    paramMap.put("createPerson", String.valueOf(userId));
                    String str = HttpHelper.postRequestResponseBodyAsString(hospitalWebSocketUrl+"chat/addMemberForGroup",paramMap);
                    System.out.println(str);
                }
            }
        }
    }


    /**
     * @Author: 杨青桦
     * @Description: 拼接警示事项提醒内容
     * @Date: 2018/4/28 13:52
     * @param list
     * @param tag
     * @return
     */
    private List<ChartsOverviewWarningView> setContent(List<ChartsOverviewWarningView> list,Integer tag){
        switch (tag){
            case 1:
            case 2:
                for(ChartsOverviewWarningView cowv : list){
                    StringBuffer sb = new StringBuffer();
                    sb.append(cowv.getDepartment()).append(": ").append(cowv.getName()).append(" ");
                    if(cowv.getRepairStatus().equals("已处理") || cowv.getRepairStatus().equals("已指派")){
                        sb.append("已指派 ");
                    }
                    if(!StringUtils.isEmpty(cowv.getServiceProvider())){
                        sb.append(cowv.getServiceProvider()).append(" ");
                    }
                    if(!StringUtils.isEmpty(cowv.getResponsible())){
                        sb.append("工程师:").append(cowv.getResponsible()).append(" ");
                    }
                    if(!cowv.getRepairStatus().equals("已处理") && !cowv.getRepairStatus().equals("已指派")){
                        sb.append(cowv.getRepairStatus()).append(" ");
                    }
                    sb.append("已故障").append(TimeUnitConvertUtil.convert(cowv.getHaveFaultMin()));
                    cowv.setContent(sb.toString());
                }
                break;
            case 3:
                for(ChartsOverviewWarningView cowv : list){
                    StringBuffer sb = new StringBuffer();
                    sb.append(cowv.getDepartment()).append(": ").append(cowv.getName()).append(" ").append(cowv.getPlanCompulsoryDate());
                    cowv.setContent(sb.toString());
                }
                break;
            case 5:
                for(ChartsOverviewWarningView cowv : list){
                    StringBuffer sb = new StringBuffer();
                    sb.append(cowv.getDepartment()).append(": ").append(cowv.getName()).append(" ").append(cowv.getParameterName()).append(" ")
                    .append(cowv.getPoliceLevel());
                    cowv.setContent(sb.toString());
                }
                break;
            case 6:
                for(ChartsOverviewWarningView cowv : list){
                    StringBuffer sb = new StringBuffer();
                    sb.append(cowv.getDepartment()).append(": ").append(cowv.getName()).append(" ").append(cowv.getPlanUpkeepDate())
                    .append("已指派 ");
                    if(!StringUtils.isEmpty(cowv.getServiceProvider())){
                        sb.append(cowv.getServiceProvider()).append(" ");
                    }
                    if(!StringUtils.isEmpty(cowv.getResponsible())){
                        sb.append("工程师:").append(cowv.getResponsible()).append(" ");
                    }
                    cowv.setContent(sb.toString());
                }
                break;
            case 7:
                for(ChartsOverviewWarningView cowv : list){
                    StringBuffer sb = new StringBuffer();
                    sb.append(cowv.getDepartment()).append(": ").append(cowv.getName()).append(" ").append(cowv.getRepairStatus());
                    cowv.setContent(sb.toString());
                }


        }
        return list;
    }

}
